// const io = require("socket.io")(); //返回一个io实例对象
const http = require("http");
const SocketServer = require("socket.io");
const config = require("./config/config")
const ip = require('ip');
const path = require('path')
const url = require("url");
const express = require("express");
const ws = require("ws")
const fs = require("fs")
const CircularJSON = require('circular-json');
const CronJob = require('cron').CronJob;

//启动服务端口
//简历2http服务
var myip = ip.address();
let app = express(); //全自动小型http 及其常用服务框架处理集成 

// app.use(express.static(path.join(process.cwd(), "src")));
//socket.io的配置参数
const options = {
    path: "/ws", //配置使用客户端框架的js文件目录
    serveClient: true, //是否提供客户端socket框架的支持
}


let socketApp = http.createServer(app)
// const io = new SocketServer(options); //返回一个io实例对象
const io = require('socket.io')(socketApp, options); //实例化socket.io 实例，并且使用与Server服务一样的端口
// const io = require('socket.io')(socketApp, options);


// 设置静态文件目录路由和模板引擎
app.set('view engine', 'ejs')
app.set('views', "./src")
// app.engine('html', require('ejs').renderFile);

const staticRoot = path.join(process.cwd(), 'src');
// console.log("静态文件目录设置为：", staticRoot)
app.use(express.static(staticRoot));

const router = require('./router');
router(app); //自动路由


socketApp.listen(config.ws_port, (error) => {
    if (error) {
        console.log('你的ws服务器启动错误', error);
    } else {
        console.log('你的ws和http服务器已经开启在  http://' + myip + ':' + config.ws_port);

    }
});


    var id_all = [];
    var admin_id = 0;
    var userNB = 1;
    var userNBs=[];
    var  adminUID=0;
    //服务端的 连接事件（只要客户端有接入就会触发）
    io.on("connection", (socket) => {

        id_all.push(socket.id); //保存每次连接的用户id
        userNBs.push(":用户"+userNB,)
        var data_json = {
            id: socket.id,
            data: {
                msg: "客户端用户ID列表"
            },
            userList: id_all,
            Urlname: socket.nsp.name,
            userNB: userNBs,
            adminID: adminUID
        }
        userNB++;
    
        console.log('有链接请求', socket.id, "id_all:", id_all)
        //每次有链接更新列表发给admin
        socket.broadcast.emit("pusll-server-admin", data_json); 


        // tuich突出前端关闭网页退出  //保存更新用户列表函数
        socket.on('disconnect', (res) => {

            var newId_ALL = (id_all.filter((item_value) => {
                return item_value != socket.id;
            }))
            id_all = newId_ALL;
            data_json.userList = newId_ALL;
            data_json.data.msg = "更新客户端用户ID列表"
            socket.broadcast.emit("pusll-server-admin", data_json); //列表发给admin
            // console.log('前端用户退出!', res, socket.id, "newId_ALL", newId_ALL)

        })





        //针对一些接入的端，进行事件绑定 - 绑定一个发送消息者消息事件
        socket.on("send-message-event", (data) => {
           
            //然后将接受的消息 ，推送（广播）给除发送者以外的所有人
           data_json.adminID=adminUID;
          
            if (!data.toall && data.adminID != 0 |adminUID!=0 ) {
                var code=data.adminID!=0?data.adminID:adminUID
                data_json.data.msg=data.msg
                console.log("code:",code)
                console.log("监听到客户端发送消息者发送事件1", data);
                io.sockets.connected[code].emit("pusll-message-event", data_json); ///发给指定ID用户 这里为admin 前台
            } else {
                data_json.data.msg=data.msg
                socket.broadcast.emit("pusll-message-event", data_json); //发给全部
                console.log("监听到客户端发送消息者发送事件2", data);
            }

        })


        //顶一个保存前端管理人员Id的变量
        socket.on("send-message-selectUser", (data) => {
            console.log("监听到客服(admin)前端回发送消息给指定客户端事件", data);
            //然后将接受的消息 ，推送（广播）给除发送者以外的所有人
            data_json = {
                id: socket.id,
                data: {
                    msg: data.msg
                },
                Urlname: socket.nsp.name
            }
            if (data.id && data.id != "" && data.id != 0) {
                io.sockets.connected[data.id].emit("pusll-message-event", data_json);
            } else {
                console.log("id管理端发来的指定id错误")
            }
        })



        //收到初次  启动的admin前台确认系信息 此处首次刷新还未建立连接情况下不能使用点对点发送
        socket.on('admin-to-server', (data) => {
            // console.log("收到管理前台的身份确认", data);
            if (data.adminID) {
                data_json.data.msg=data.msg;
                adminUID=socket.id;
                data_json.adminID=socket.id;
                console.log(data.adminID,socket.id, "前台确认上线了",data)
                socket.broadcast.emit("pusll-message-event", data_json);
                // var time=setTimeout(()=>{
                //         socket.broadcast.emit("pusll-server-admin", data_json);
                // },1000)
                // io.socket.connected[socket.id].emit("pusll-server-admin", data_json); //列表发给admin
            } else {
                console.log("前台未有发来adminID", data.adminID)

            }
        })





        //轮询前端各个客户端是否在线
        new CronJob('*/5 * * * * ', function () { //总共6个星  填一个少一个
            // console.log('You will see this message every second');
            data_json.data.msg = '更新用户列表'
            data_json.data.ask = 'are you live?'
            socket.broadcast.emit("server-ask-client", data_json); //发给全部
        }, null, true, 'America/Los_Angeles');






        //保存soket链接信息到json
        let data = CircularJSON.stringify(socket);
        fs.writeFile(path.join(__dirname, 'config', 'socket.json'), data, function (err) {
            if (err) {
                throw err;
            }
        });


        
    })


